package com.nike.amoeba.viewmodel

import androidx.fragment.app.Fragment
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.blankj.utilcode.util.LogUtils
import com.blankj.utilcode.util.TimeUtils
import com.blankj.utilcode.util.ToastUtils
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import com.nike.amoeba.R
import com.nike.amoeba.SingleLiveEvent
import com.nike.amoeba.base.MyBaseViewModel
import com.nike.amoeba.bean.AppRoomDataBase
import com.nike.amoeba.bean.DataBean
import com.nike.amoeba.bean.db.StockManageEpcBean
import com.nike.amoeba.ext.WAREHOUSE_RU_TYPE
import com.nike.amoeba.ext.showMessage
import com.nike.amoeba.network.REQUEST_SUCCESS
import com.nike.amoeba.network.apiService
import com.nike.amoeba.network.stateCallback.ListDataUiState
import com.nike.amoeba.ui.frg.StockChuEpcFrg
import com.nike.amoeba.ui.frg.StockManageListFrg
import com.nike.amoeba.ui.frg.StockRuEpcFrg
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import me.hgj.jetpackmvvm.base.appContext
import me.hgj.jetpackmvvm.callback.databind.StringObservableField
import me.hgj.jetpackmvvm.ext.requestNoCheck
import org.json.JSONArray
import org.json.JSONObject

/**
 * @Author nike
 * @Date 2023/7/6 18:07
 * @Description
 */
class StockManageModel : MyBaseViewModel() {

    var listBean: MutableLiveData<ListDataUiState<DataBean>> = MutableLiveData()

    val stockManageEpcDao = AppRoomDataBase.get().getStockManageEpcDao()

    var state = StringObservableField()

    var save = StringObservableField()

    var searchText: MutableLiveData<String> = MutableLiveData()

    var assetListBean = ArrayList<DataBean>()

    var storageUnitListBean = ArrayList<DataBean>()

    var storageUnitList: MutableLiveData<ArrayList<DataBean>> = MutableLiveData()

    var assetList: MutableLiveData<ArrayList<DataBean>> = MutableLiveData()

    var isSaveCallback: SingleLiveEvent<ArrayList<DataBean>> = SingleLiveEvent()

    var updateStockManageListCallback: SingleLiveEvent<Boolean> = SingleLiveEvent()

    fun getInboundPrint(batchNo: String?, roNo: String?, warehouseType: Int, code: String?) {
        requestNoCheck({ apiService.getInboundPrint(batchNo, roNo, "", code) }, {
            if (it.code == REQUEST_SUCCESS) {
                val data = it.data
                if (data != null) {
                    val datalist = data.datalist
                    viewModelScope.launch(Dispatchers.IO) {
                        datalist?.forEach {
                            val bean = stockManageEpcDao.find(it.EPCRoNo!!)
                            if (bean != null && it.EPCRoNo.equals(bean.EPCRoNo)) {
                                it.isCheckedSave = bean.isCheckedSave
                                it.Type = bean.type
                                it.SRoNo = bean.SRoNo
                                it.SUnitName = bean.SUnitName
                            }
                        }
                        withContext(Dispatchers.Main) {
                            listBean.postValue(
                                ListDataUiState(
                                    isRefresh = true,
                                    isSuccess = true,
                                    listData = datalist as java.util.ArrayList<DataBean>,
                                    isFirstEmpty = if (datalist!!.size == 0) true else false
                                )
                            )
                            val asset = data.AssetList
                            if (!asset.isNullOrEmpty()) {
                                assetListBean.clear()
                                assetListBean.add(DataBean(text = appContext.getString(R.string.all_assest)))
                                asset.forEach {
                                    var bean = DataBean()
                                    bean.text = it.AssetNo
                                    bean.content = it.ARoNo
                                    assetListBean.add(bean)
                                }
                                //                        assetList.value = assetListBean
                            }
                            val StorageUnit = data.StorageUnitList
                            if (!StorageUnit.isNullOrEmpty()) {
                                storageUnitListBean.clear()
                                storageUnitListBean.add(DataBean(text = appContext.getString(R.string.all_locations)))
                                StorageUnit.forEach {
                                    var bean = DataBean()
                                    bean.text = it.SUnitName
                                    bean.content = it.SRoNo
                                    storageUnitListBean.add(bean)
                                }
                                storageUnitList.value = storageUnitListBean
                            }
                        }
                    }
                }
            }
        }, {
            //请求失败 网络异常回调在这里
            loadingChange.dismissDialog
            ToastUtils.showShort(it.throwable!!.message)
            LogUtils.e(it.throwable)
        }, false)
    }

    fun onWarehouseOrderList(warehouseType: Int, code: String?) {
        if (warehouseType == WAREHOUSE_RU_TYPE) {
            requestNoCheck({ apiService.getWarehouseList(code) }, {
                if (it.code == REQUEST_SUCCESS) {
                    val data = it.data
                    listBean.postValue(
                        ListDataUiState(
                            isRefresh = true,
                            isSuccess = true,
                            listData = data as java.util.ArrayList<DataBean>,
                            isFirstEmpty = if (data!!.size == 0) true else false
                        )
                    )

                    viewModelScope.launch(Dispatchers.IO) {
                        stockManageEpcDao.deleteAll()
                        stockListDao.deleteAll()
                    }
                }
            }, {
                //请求失败 网络异常回调在这里
                loadingChange.dismissDialog
                ToastUtils.showShort(it.throwable!!.message)
                LogUtils.e(it.throwable)
            }, false)
        } else {
            requestNoCheck({ apiService.getOutWarehouseList(code) }, {
                if (it.code == REQUEST_SUCCESS) {
                    val data = it.data
                    listBean.postValue(
                        ListDataUiState(
                            isRefresh = true,
                            isSuccess = true,
                            listData = data as java.util.ArrayList<DataBean>,
                            isFirstEmpty = if (data!!.size == 0) true else false
                        )
                    )
                    viewModelScope.launch(Dispatchers.IO) {
                        stockManageEpcDao.deleteAll()
                        stockListDao.deleteAll()
                    }
                }
            }, {
                //请求失败 网络异常回调在这里
                loadingChange.dismissDialog
                ToastUtils.showShort(it.throwable!!.message)
                LogUtils.e(it.throwable)
            }, false)
        }
    }

    fun onStockManageList(batchNo: String?, stockType: Int, code: String?) {
        if (stockType == WAREHOUSE_RU_TYPE) {
            requestNoCheck({ apiService.getInboundOrderDetail2(batchNo, code) }, {
                val json = JSONObject(it.string())
                if (json.optInt("code") == REQUEST_SUCCESS) {
                    val data = json.optJSONObject("data")
                    onWarehouseListDetail(data, stockType, batchNo)
                }
            }, {
                //请求失败 网络异常回调在这里
                loadingChange.dismissDialog
                ToastUtils.showShort(it.throwable!!.message)
                LogUtils.e(it.throwable)
            }, false)
        } else {
            requestNoCheck({ apiService.getOutboundOrderDetail(batchNo, code) }, {
                val json = JSONObject(it.string())
                if (json.optInt("code") == REQUEST_SUCCESS) {
                    val data = json.optJSONObject("data")
                    onWarehouseListDetail(data, stockType, batchNo)
                }
            }, {
                //请求失败 网络异常回调在这里
                loadingChange.dismissDialog
                ToastUtils.showShort(it.throwable!!.message)
                LogUtils.e(it.throwable)
            }, false)
        }
    }

    private fun onWarehouseListDetail(data: JSONObject, warehouseType: Int, batchNo: String?) {
        viewModelScope.launch(Dispatchers.IO) {
            if (data != null) {
                val boundOrderList: JSONArray
                if (warehouseType == WAREHOUSE_RU_TYPE) {
                    boundOrderList = data.optJSONArray("InboundOrderList")
                } else {
                    boundOrderList = data.optJSONArray("OutboundOrderList")
                }
                if (boundOrderList != null) {
                    for (i in 0 until boundOrderList.length()) {
                        val obj = boundOrderList.optJSONObject(i)
                        val listStr = ArrayList<DataBean>()
                        var allNUm = 0
                        val Info = obj.optJSONArray("Info")
                        for (i in 0 until Info.length()) {
                            val infoObj = Info.optJSONObject(i)
                            val mURoNoList = stockManageEpcDao.findSkuAll(obj.optString("id"), infoObj.optString("MURoNo"), batchNo!!)
                            infoObj.put("allNum", mURoNoList.size)
                            allNUm += infoObj.optInt("NeedNum")
                        }
                        //设置是否能上传
                        val all = stockManageEpcDao.findSkuAll(obj.optString("id"), batchNo!!)
                        val orderEpc = obj.optJSONObject("OrderEpc")
                        if (orderEpc != null){
                            /*if (orderEpc.optInt("Count") == all.size){
                                obj.put("Type", 1)
                            }*/
                            if (allNUm == all.size){
                                obj.put("Type", 1)
                            }
                        }
                        val attributes = obj.optJSONObject("Attributes")
                        val keys: Iterator<String> = attributes.keys()
                        while (keys.hasNext()) {
                            var key = keys.next()
                            val value: String = attributes.getString(key)
                            val bean = DataBean()
                            if (key.contains("InStorage-")) {
                                key = key.substring(10)
                            } else if (key.contains("OutStorage-")) {
                                key = key.substring(11)
                            }
                            bean.Title = key
                            bean.content = value
                            listStr.add(bean)
                        }
                        obj.put("content", Gson().toJson(listStr).toString())
                    }
                }
                // 在处理完 InboundOrderList 后，将其转换为 DataBean 对象的列表
                val listType = object : TypeToken<List<DataBean>>() {}.type
                val list: ArrayList<DataBean> = Gson().fromJson(boundOrderList.toString(), listType)

                withContext(Dispatchers.Main) {
                    listBean.value = (
                            ListDataUiState(
                                isRefresh = true,
                                isSuccess = true,
                                listData = list as java.util.ArrayList<DataBean>,
                                isFirstEmpty = if (list!!.size == 0) true else false
                            )
                    )
                }
            }
        }

    }

    fun getOutboundPrint(batchNo: String?, roNo: String?, code: String?) {
        requestNoCheck({ apiService.getOutboundPrint(batchNo, roNo, "", code) }, {
            if (it.code == REQUEST_SUCCESS) {
                val data = it.data
                if (data != null) {
                    val datalist = data.datalist
                    viewModelScope.launch(Dispatchers.IO) {
                        datalist?.forEach { dataBean ->
                            dataBean.EPCList?.forEach {
                                val bean = stockManageEpcDao.find(it.EPCRoNo!!)
                                if (bean != null && it.EPCRoNo.equals(bean.EPCRoNo)) {
                                    it.Type = bean.type
                                }
                            }
                            //计算出库数量是否满足
                            val count = dataBean.EPCList?.count { it.Type == 1 }
                            if (count == dataBean.NeedNum) {
                                dataBean.isCheckedSave = true
                            }
                        }
                        withContext(Dispatchers.Main) {
                            listBean.postValue(
                                ListDataUiState(
                                    isRefresh = true,
                                    isSuccess = true,
                                    listData = datalist as java.util.ArrayList<DataBean>,
                                    isFirstEmpty = if (datalist!!.size == 0) true else false
                                )
                            )
                        }
                    }
                }
            }
        }, {
            //请求失败 网络异常回调在这里
            loadingChange.dismissDialog
            ToastUtils.showShort(it.throwable!!.message)
            LogUtils.e(it.throwable)
        }, false)
    }

    fun onSave(frg: StockChuEpcFrg, list: java.util.ArrayList<DataBean>, stockId: String?) {
        viewModelScope.launch(Dispatchers.IO) {
            var newList = ArrayList<DataBean>()
            list.forEach {dataBean ->
                dataBean.EPCList?.forEach {
                    if (!dataBean.isCheckedSave && it.Type == 1) {
                        var bean = stockManageEpcDao.findSkuId(stockId!!, it.EPCRoNo!!, batchNo.get())
                        if (bean == null){
                            bean = StockManageEpcBean()
                        }
                        bean.id = dataBean.id
                        bean.ids = stockId
                        bean.EPCRoNo = it?.EPCRoNo
                        bean.epc = it?.EPC
                        bean.SUnitName = dataBean.SUnitName
                        bean.MURoNo = dataBean.MURoNo
                        bean.SRoNo = dataBean.SRoNo
                        bean.type = 1
                        bean.BatchNo = batchNo.get()
                        bean.createTime = TimeUtils.getNowString()
                        stockManageEpcDao.insertOrUpdate(bean)
                    }
                }
                val count = list.sumBy {
                    it.EPCList?.count { it.Type == 1 } ?: 0
                }
                if (count == dataBean.NeedNum) {
                    dataBean.isCheckedSave = true
                    dataBean.Type = 1
                }
                newList.add(dataBean)
            }
            withContext(Dispatchers.Main) {
                listBean.value = ListDataUiState(
                    listData = newList as ArrayList<DataBean>,
                    isSuccess = true,
                    isRefresh = true,
                    isFirstEmpty = if (newList!!.size == 0) true else false)
                frg.showMessage(frg.getString(R.string.release_success))
            }
        }

        /*mFilterList.forEach { dataBean ->
                    dataBean.EPCList?.forEach {
                        if (!dataBean.isCheckedSave && it.Type == 1) {
                            var epcBean = StockManageEpcBean()
                            epcBean.EPCRoNo = it.EPCRoNo
                            epcBean.MURoNo = dataBean.MURoNo
                            epcBean.ARoNo = dataBean.ARoNo
                            epcBean.SRoNo = dataBean.SRoNo
                            epcBean.createTime = TimeUtils.getNowString()
                            epcBean.type = it.Type
                            epcBean.id = batchNo + aRoNo + dataBean.MURoNo
                            stockManageEpcDao.insertOrUpdate(epcBean)
                        }
                    }
                    val count = mFilterList.sumBy {
                        it.EPCList?.count { it.Type == 1 } ?: 0
                    }
                    if (count == dataBean.NeedNum) {
                        dataBean.isCheckedSave = true
                    }
                }*/
    }

    fun onSubmit(
        frg: StockManageListFrg,
        mFilterList: java.util.ArrayList<DataBean>,
        batchNo: String?,
        warehouseType: Int,
        code: String?
    ) {
        val hasTypeOne = mFilterList.any { it.Type == 1 }
        if (!hasTypeOne) {
//            requireActivity.showMessage(appContext.getString(R.string.no_data))
            return
        }
        viewModelScope.launch(Dispatchers.IO) {
            var ja = JSONArray()
            mFilterList.forEach { dataBean ->
                if (dataBean.Type == 1) {
                    stockManageEpcDao.findSkuAll(dataBean.id!!, batchNo!!).forEach {
                        var obj = JSONObject().apply {
                            put("EPCRoNo", it.EPCRoNo)
                            put("createTime", it.createTime)
                            put("ARoNo", it.ARoNo)
                            put("sRoNo", it.SRoNo)
                            put("MURoNo", it.MURoNo)
                        }
                        ja.put(obj)
                    }
                }
            }
            if (ja.length() == 0) return@launch
            withContext(Dispatchers.Main) {
                if (warehouseType == WAREHOUSE_RU_TYPE) {
                    requestNoCheck({ apiService.UpdateInbound(ja.toString(), batchNo, code) }, {
                        if (it.code == REQUEST_SUCCESS) {
                            viewModelScope.launch(Dispatchers.IO) {
                                val indicesToRemove = mutableListOf<Int>()
                                mFilterList.forEachIndexed { index, dataBean ->
                                    if (dataBean.Type == 1) {
                                        stockManageEpcDao.deleteIdAll(batchNo + dataBean.RoNo + dataBean.MURoNo)
                                        stockListDao.deleteIdAll(batchNo + dataBean.RoNo + dataBean.MURoNo)
                                        indicesToRemove.add(index)
                                    }
                                }
                                indicesToRemove.reversed().forEach { index ->
                                    mFilterList.removeAt(index)
                                }
                                withContext(Dispatchers.Main) {
                                    var list = ArrayList<DataBean>()
                                    list.addAll(mFilterList)
                                    listBean.value = ListDataUiState(
                                        isSuccess = true,
                                        isRefresh = true,
                                        listData = list,
                                        isFirstEmpty = if (list!!.size == 0) true else false
                                    )
                                    frg.showMessage(appContext.getString(R.string.text4))
                                }
                            }
                        }
                    }, {
                        //请求失败 网络异常回调在这里
                        loadingChange.dismissDialog
                        ToastUtils.showShort(it.throwable!!.message)
                        LogUtils.e(it.throwable)
                    }, true, appContext.getString(R.string.loading))
                } else {
                    requestNoCheck({ apiService.UpdateOutbound(ja.toString(), batchNo, code) }, {
                        if (it.code == REQUEST_SUCCESS) {
                            viewModelScope.launch(Dispatchers.IO) {
                                val indicesToRemove = mutableListOf<Int>()
                                mFilterList.forEachIndexed { index, dataBean ->
                                    if (dataBean.Type == 1) {
                                        stockManageEpcDao.deleteIdAll(batchNo + dataBean.RoNo + dataBean.MURoNo)
                                        stockListDao.deleteIdAll(batchNo + dataBean.RoNo + dataBean.MURoNo)
                                        indicesToRemove.add(index)
                                    }
                                }
                                indicesToRemove.reversed().forEach { index ->
                                    mFilterList.removeAt(index)
                                }
                                withContext(Dispatchers.Main) {
                                    var list = ArrayList<DataBean>()
                                    list.addAll(mFilterList)
                                    listBean.value = ListDataUiState(
                                        isSuccess = true,
                                        isRefresh = true,
                                        listData = list,
                                        isFirstEmpty = if (list!!.size == 0) true else false
                                    )
                                    frg.showMessage(appContext.getString(R.string.text4))
                                }
                            }
                        }
                    }, {
                        //请求失败 网络异常回调在这里
                        loadingChange.dismissDialog
                        ToastUtils.showShort(it.throwable!!.message)
                        LogUtils.e(it.throwable)
                    }, true, appContext.getString(R.string.loading))
                }
            }
        }
    }

    fun onRequest(bean: DataBean) {
        viewModelScope.launch(Dispatchers.IO) {
            val orderEpc = bean.OrderEpc
            if (orderEpc != null){
                val list = orderEpc.StorageUnitList
                if (!list.isNullOrEmpty() && list.size != 0){
                    list.forEach {
                        it.text = it.SUnitName
                    }
                    storageUnitListBean.addAll(list)
//                    storageUnitList.postValue(storageUnitListBean)
                }
                var newList = ArrayList<DataBean>()
                orderEpc.datalist?.forEach {
                    /*val findAll = stockManageEpcDao.findSkuAll(bean.id!!, batchNo.get())
                    findAll.forEach {bean->
                        *//*if (findAll != null && bean.type == 1 && bean.EPCRoNo.equals(it.EPCRoNo)){
                            it.SUnitName = bean.SUnitName
                            it.SRoNo = bean.SRoNo
//                            it.list = list
                            newList.add(it)
                        }*//*
                    }*/
                    it.StorageUnitList = list
                    val bean = stockManageEpcDao.find(it.EPCRoNo!!)
                    if (bean != null && it.EPCRoNo == bean.EPCRoNo && batchNo.get() == bean.BatchNo) {
                        it.isCheckedSave = bean.isCheckedSave
                        it.Type = bean.type
                        it.SRoNo = bean.SRoNo
                        it.SUnitName = bean.SUnitName
                        it.isCheckedSave = bean.isCheckedSave
                    }
                }
                newList.addAll(orderEpc.datalist!!)
                listBean.postValue(ListDataUiState(
                    isRefresh = true,
                    listData = newList, isSuccess = true, isFirstEmpty = if (newList!!.size == 0) true else false)
                )
            }
        }
    }

    fun onSave(storageUnitBean: DataBean?, stockId: String?, list: MutableList<DataBean>, frg: Fragment) {
        viewModelScope.launch(Dispatchers.IO) {
            var newList = ArrayList<DataBean>()
            list.forEach {
                if (it.Type == 1){
                    var bean = stockManageEpcDao.findSkuId(stockId!!, it.EPCRoNo!!, batchNo.get())
                    if (bean == null){
                        bean = StockManageEpcBean()
                    }
                    bean.id = it.id
                    bean.ids = stockId
                    bean.EPCRoNo = it.EPCRoNo
                    bean.epc = it.EPC
                    bean.MURoNo = it.MURoNo
                    bean.BatchNo = batchNo.get()
                    bean.type = 1
                    bean.createTime = TimeUtils.getNowString()
                    bean.SUnitName = it.SUnitName
                    bean.SRoNo = it.SRoNo
                    bean.isCheckedSave = true
                    stockManageEpcDao.insertOrUpdate(bean)
                }
                newList.add(it)
            }
            withContext(Dispatchers.Main) {
                listBean.value = ListDataUiState(
                    listData = newList as ArrayList<DataBean>,
                    isSuccess = true,
                    isRefresh = true,
                    isFirstEmpty = if (newList!!.size == 0) true else false)
                frg.showMessage(frg.getString(R.string.release_success))
                updateStockManageListCallback.value = true
            }
        }

        /*viewModelScope.launch(Dispatchers.IO) {
            var newList = ArrayList<DataBean>()
            list.forEach {
                val bean = stockManageEpcDao.findSkuId(stockId!!, it.EPCRoNo!!, batchNo.get())
                if (bean != null && it.Type == 1){
                    it.SUnitName = storageUnitBean.SUnitName
                    it.SRoNo = storageUnitBean.SRoNo

                    bean.SUnitName = storageUnitBean.SUnitName
                    bean.SRoNo = storageUnitBean.SRoNo
                    bean.isCheckedSave = true
                    stockManageEpcDao.insertOrUpdate(bean)
                }
                newList.add(it)
            }

            withContext(Dispatchers.Main) {
                listBean.value = ListDataUiState(
                    listData = newList as ArrayList<DataBean>,
                    isSuccess = true,
                    isRefresh = true,
                    isFirstEmpty = if (newList!!.size == 0) true else false)
                frg.showMessage(frg.getString(R.string.release_success))
            }
        }*/
    }

    fun onChuRequest(bean: DataBean, stockId: String?) {
        viewModelScope.launch(Dispatchers.IO) {
            var newList = ArrayList<DataBean>()
            bean.OrderEpc?.datalist?.forEach {bean ->
                bean.EPCList?.forEach {
                    stockManageEpcDao.findMURoNoAll(bean.id!!)?.forEach {epcBean ->
                        if (it.EPCRoNo.equals(epcBean.EPCRoNo)){
                            it.Type = epcBean.type
                        }
                    }
                }
                newList.add(bean)
            }
            listBean.postValue(
                ListDataUiState(
                    isRefresh = true,
                    isSuccess = true,
                    listData = newList as java.util.ArrayList<DataBean>,
                    isFirstEmpty = if (newList!!.size == 0) true else false
                )
            )
        }

    }


}